/**
 * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.sys.service;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jeeplus.core.service.TreeService;
import com.jeeplus.sys.constant.CommonConstants;
import com.jeeplus.sys.constant.enums.OfficeTypeEnum;
import com.jeeplus.sys.domain.Office;
import com.jeeplus.sys.mapper.OfficeMapper;
import com.jeeplus.sys.service.dto.OfficeDTO;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 机构Service
 *
 * @author jeeplus
 * @version 2021-05-16
 */
@Service
@Transactional
public class OfficeService extends TreeService<OfficeMapper, Office> {


    /**
     * 获取列表
     *
     * @return
     */
    public List<OfficeDTO> findList(String parentId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.like(StringUtils.isNotBlank(parentId), "a.parent_ids", "," + parentId + ",");
        queryWrapper.eq("a.del_flag", 0);
        queryWrapper.orderByAsc("a.sort");
        List<OfficeDTO> list = baseMapper.findList(queryWrapper);
        for(OfficeDTO officeDTO:list){
            officeDTO.setUserList(baseMapper.getDeptUserType(officeDTO.getId()));
        }
        return list;
    }

    public List<OfficeDTO> getRootTree(String parentId, List<OfficeDTO> list, String extId, String type, String showAll) {
        List<OfficeDTO> offices = Lists.newArrayList();
        parentId = StrUtil.isEmpty(parentId) ? OfficeDTO.getRootId() : parentId;
        for (OfficeDTO root : list) {
            if (parentId.equals(root.getParentId())) {
                if (this.isUseAble(extId, type, root, showAll)) {
                    // 不是被排除节点的子节点
                    List<OfficeDTO> officeList = formatListToTree(root, list, extId, type, showAll);
                    offices.addAll(officeList);
                }
            }
        }
        return offices;
    }


    public List<OfficeDTO> formatListToTree(OfficeDTO root, List<OfficeDTO> allList, String extId, String type, String showAll) {
        String rootId = root.getId();

        // type为2时，是选择部门，因此禁用type为1的公司节点
        if (OfficeTypeEnum.OFFICE.getValue().equals(type) && root.getType().equals(OfficeTypeEnum.COMPANY.getValue())) {
            root.setDisabled(true);
        } else {
            root.setDisabled(false);
        }
        // 最终的树形态
        List<OfficeDTO> trees = Lists.newArrayList();

        // 把需要构造树的所有列表, 根据以父id作为key, 整理为列表
        Map<String, List<OfficeDTO>> treeMap = Maps.newHashMap();
        for (OfficeDTO entity : allList) {
            List<OfficeDTO> offices = treeMap.get(entity.getParent().getId());
            if (offices == null) {
                offices = Lists.newLinkedList();
            }

            if (this.isUseAble(extId, type, root, showAll)) {

                // 如果是查找公司，只返回公司数据，如果是查询部门，则一起返回公司部门数据
                if (OfficeTypeEnum.COMPANY.getValue().equals(type) && entity.getType().equals(type)
                        || OfficeTypeEnum.OFFICE.getValue().equals(type)
                        || StrUtil.isBlank(type)
                ) {

                    // type为2时，是选择部门，因此禁用type为1的公司节点
                    if (OfficeTypeEnum.OFFICE.getValue().equals(type) && entity.getType().equals(OfficeTypeEnum.COMPANY.getValue())) {
                        entity.setDisabled(true);
                    } else {
                        entity.setDisabled(false);
                    }
                    offices.add(entity);
                }

                treeMap.put(entity.getParent().getId(), offices);
            }
        }

        // 开始递归格式化
        List<OfficeDTO> children = treeMap.get(rootId);
        if (children != null) {
            for (OfficeDTO parent : children) {
                formatFillChildren(parent, treeMap);
                trees.add(parent);
            }
        }

        root.setChildren(trees);
        return Lists.newArrayList(root);
    }

    /**
     * 从treeMap中取出子节点填入parent, 并递归此操作
     **/
    private void formatFillChildren(OfficeDTO parent, Map<String, List<OfficeDTO>> treeMap) {

        List<OfficeDTO> children = treeMap.get(parent.getId());
        parent.setChildren(children);
        if (children != null && !children.isEmpty()) {
            for (OfficeDTO child : children) {
                formatFillChildren(child, treeMap);
            }
        }
    }

    private boolean isUseAble(String extId, String type, OfficeDTO dto, String showAll) {
        return (StringUtils.isBlank(extId) || (extId != null && !extId.equals(dto.getId()) && dto.getParentIds().indexOf("," + extId + ",") == -1))
                && (type == null || (type != null && (type.equals(OfficeTypeEnum.COMPANY.getValue()) ? type.equals(dto.getType()) : true)))
                && (CommonConstants.YES.equals(showAll) || CommonConstants.YES.equals(dto.getUseable()));
    }


    public List<Office> getOfficesTree() {
        // 获取所有的办公室数据
        List<Office> allOffices = baseMapper.findAllOffices();

        // 查询根级数据（parent_id = 0）
        List<Office> rootOffices = new ArrayList<>();
        for (Office office : allOffices) {
            if ("0".equals(office.getParentId())) {  // 根级数据的 parentId 是 "0"
                rootOffices.add(office);
            }
        }

        // 为每个根级数据递归查找子级
        for (Office office : rootOffices) {
            office.setChildren(getChildren(allOffices, office.getId()));  // 设置子节点
        }

        return rootOffices;  // 返回包含根节点和子节点的树形结构
    }

    private List<Office> getChildren(List<Office> allOffices, String parentId) {
        List<Office> children = new ArrayList<>();

        // 遍历所有的办公室数据，找到属于当前 parentId 的子节点
        for (Office office : allOffices) {
            if (parentId.equals(office.getParentId())) {
                office.setChildren(getChildren(allOffices, office.getId()));  // 递归查找子节点
                children.add(office);
            }
        }

        return children;
    }

    public List<Office> getSelfAndParent(String id) {
        List<Office> offices = new ArrayList<>();
        boolean getNext = true;
        String searchId = id;
        while (getNext) {
            Office office = baseMapper.selectById(searchId);
            if (office == null) {
                getNext = false;
            } else {
                offices.add(office);
                if ("0".equals(office.getParentId()))
                    getNext = false;
                else
                    searchId = office.getParentId();
            }
        }
        return offices;
    }

    public Office get(String id) {
        return baseMapper.selectById(id);
    }

    public List<String> getOfficesTreeByParentId(String parentId) {
        String parent = "0";
        if(StringUtils.isNotEmpty(parentId)){
            parent = parentId;
        }
        // 获取所有的办公室数据
        List<Office> allOffices = baseMapper.findAllOffices();

        // 查询根级数据（parent_id = 0）
        List<Office> rootOffices = new ArrayList<>();
        for (Office office : allOffices) {
            if (parent.equals(office.getParentId())) {  // 根级数据的 parentId 是 "0"
                rootOffices.add(office);
            }
        }

        // 为每个根级数据递归查找子级
        for (Office office : rootOffices) {
            office.setChildren(getChildren(allOffices, office.getId()));  // 设置子节点
        }
        List<String> res = new ArrayList<>();
        if(!CollectionUtils.isEmpty(rootOffices)){
            rootOffices.forEach(e->{
                res.add(e.getId());
            });
        }

        return res;  // 返回包含根节点和子节点的树形结构
    }

}

